package com.xhwl.logistics.open;

import com.alibaba.fastjson.JSON;
import com.xhwl.common.exception.BusinessException;
import com.xhwl.logistics.bo.cent.DeviceBO;
import com.xhwl.logistics.bo.cent.ProjectBO;
import com.xhwl.logistics.bo.cent.VehicleIntegratedConfigBO;
import com.xhwl.logistics.converter.mapstruct.CentDeviceConverter;
import com.xhwl.logistics.converter.mapstruct.VehicleAccessRecordConverter;
import com.xhwl.logistics.converter.mapstruct.VehiclePayRecordConverter;
import com.xhwl.logistics.dto.ResponseCommonPushJieShunDTO;
import com.xhwl.logistics.dto.query.CarDeviceJieShunDTO;
import com.xhwl.logistics.dto.query.CarInJieShunDTO;
import com.xhwl.logistics.dto.query.CarOutJieShunDTO;
import com.xhwl.logistics.dto.query.CarPayJieShunDTO;
import com.xhwl.logistics.dto.query.CommonPushJieShunDTO;
import com.xhwl.logistics.entity.VehicleAccessRecord;
import com.xhwl.logistics.service.cent.QueryDeviceSecondService;
import com.xhwl.logistics.service.cent.QueryDeviceService;
import com.xhwl.logistics.service.cent.QueryProjectService;
import com.xhwl.logistics.service.impl.VehicleAccessRecordServiceImpl;
import com.xhwl.logistics.service.impl.VehiclePayRecordServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.util.Optionals;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Slf4j
//@RestController
public class JieShunDataPushController {

    @Autowired
    private QueryDeviceService queryDeviceService;

    @Autowired
    private QueryDeviceSecondService queryDeviceSecondService;

    @Autowired
    private QueryProjectService queryProjectService;

    @Autowired
    private VehicleAccessRecordServiceImpl vehicleAccessRecordService;

    @Autowired
    private VehiclePayRecordServiceImpl vehiclePayRecordService;

    @Autowired
    private VehicleAccessRecordConverter vehicleAccessRecordConverter;

    @Autowired
    private VehiclePayRecordConverter vehiclePayRecordConverter;

    @Autowired
    private CentDeviceConverter centDeviceConverter;

    @PostMapping("/jie-shun/carIn")
    public ResponseCommonPushJieShunDTO carIn(@RequestBody CommonPushJieShunDTO carInDTO) {
        log.info("JieShun push carIn start!");
        log.info("carInDTO: " + carInDTO);

        List<CarInJieShunDTO> carInJieShunDTOList = JSON.parseArray(carInDTO.getDataItems(), CarInJieShunDTO.class);
        if (1!=carInJieShunDTOList.size()) {
            throw new BusinessException("回调carIn仅支持一条记录的解析");
        }
        CarInJieShunDTO carInJieShunDTO = carInJieShunDTOList.get(0);

        Integer projectId = queryDeviceService.queryProjectIdFromIntegratedConfiguration(carInJieShunDTO.getParkCode());
        ProjectBO projectBO = queryProjectService.queryProject(projectId);

        VehicleAccessRecord vehicleAccessRecord = vehicleAccessRecordConverter.jieShun2VehicleAccessRecord(projectBO, carInJieShunDTO, 0);
        vehicleAccessRecordService.save(vehicleAccessRecord);

        log.info("JieShun push carIn end!");
        return new ResponseCommonPushJieShunDTO(0);
    }

    @PostMapping("/jie-shun/carOut")
    public ResponseCommonPushJieShunDTO carOut(@RequestBody CommonPushJieShunDTO carOutDTO) {
        log.info("JieShun push carOut start!");
        log.info("carOutDTO: " + carOutDTO);

        List<CarOutJieShunDTO> carOutJieShunDTOList = JSON.parseArray(carOutDTO.getDataItems(), CarOutJieShunDTO.class);
        if (1!=carOutJieShunDTOList.size()) {
            throw new BusinessException("回调carOut仅支持一条记录的解析");
        }
        CarOutJieShunDTO carOutJieShunDTO = carOutJieShunDTOList.get(0);

        Integer projectId = queryDeviceService.queryProjectIdFromIntegratedConfiguration(carOutJieShunDTO.getParkCode());
        VehicleAccessRecord vehicleAccessRecord = null;//vehicleAccessRecordService.getOne(new LambdaQueryWrapper<>(VehicleAccessRecord.class)
                /*.eq(VehicleAccessRecord::getProjectId, projectId)
                .eq(VehicleAccessRecord::getRecordId, carOutJieShunDTO.getInRecordId()));*/
        Optionals.ifPresentOrElse(
                Optional.ofNullable(vehicleAccessRecord),
                accessRecord -> vehicleAccessRecordService.updateById(vehicleAccessRecordConverter.toVehicleAccessRecord(carOutJieShunDTO, accessRecord.getId(), 1)),
                () -> {
                    ProjectBO projectBO = queryProjectService.queryProject(projectId);
                    vehicleAccessRecordService.save(vehicleAccessRecordConverter.jieShun2VehicleAccessRecord(projectBO, carOutJieShunDTO, 1));
                });

        log.info("JieShun push carOut end!");
        return new ResponseCommonPushJieShunDTO(0);
    }

    @PostMapping("/jie-shun/carPay")
    public ResponseCommonPushJieShunDTO carPay(@RequestBody CommonPushJieShunDTO carPayDTO) {
        log.info("JieShun push carPay start!");
        log.info("carPayDTO: " + carPayDTO);

        List<CarPayJieShunDTO> carPayJieShunDTOList = JSON.parseArray(carPayDTO.getDataItems(), CarPayJieShunDTO.class);
        if (1!=carPayJieShunDTOList.size()) {
            throw new BusinessException("回调carPay仅支持一条记录的解析");
        }
        CarPayJieShunDTO carPayJieShunDTO = carPayJieShunDTOList.get(0);

        Integer projectId = queryDeviceService.queryProjectIdFromIntegratedConfiguration(carPayJieShunDTO.getParkCode());
        vehiclePayRecordService.save(vehiclePayRecordConverter.jieShun2VehiclePayRecord(carPayJieShunDTO, projectId));

        log.info("JieShun push carPay end!");
        return new ResponseCommonPushJieShunDTO(0);
    }

    @PostMapping("/jie-shun/carDevice")
    public ResponseCommonPushJieShunDTO carDevice(@RequestBody CommonPushJieShunDTO carDeviceDTO) {
        log.info("JieShun push carDevice start!");
        log.info("carDeviceDTO: " + carDeviceDTO);

        List<CarDeviceJieShunDTO> carDeviceJieShunDTOList = JSON.parseArray(carDeviceDTO.getDataItems(), CarDeviceJieShunDTO.class);

        VehicleIntegratedConfigBO vehicleIntegratedConfigBO = queryDeviceService.queryIntegratedConfigFromParkId(carDeviceJieShunDTOList.get(0).getParkCode());
        Integer projectId = vehicleIntegratedConfigBO.getVehicleSystemInfoBO().getProjectId();
        Integer productId = vehicleIntegratedConfigBO.getVehicleSystemInfoBO().getProductId();
        Integer productCategoryId = vehicleIntegratedConfigBO.getVehicleSystemInfoBO().getProductCategoryId();

        List<DeviceBO> deviceBOListForProject = queryDeviceSecondService.queryDevicesByProjectId(vehicleIntegratedConfigBO.getVehicleSystemInfoBO().getProjectId());
        List<DeviceBO> deviceBOListForPush = centDeviceConverter.carDeviceJieShunDTOList2DeviceBOList(carDeviceJieShunDTOList, projectId, productId, productCategoryId);

        List<DeviceBO> update = new ArrayList<>();
        deviceBOListForProject.forEach(deviceBO -> {
            Optional<DeviceBO> optionalDeviceBO = deviceBOListForPush.stream().filter(deviceBOForPush -> deviceBOForPush.getNumber().equals(deviceBO.getNumber())).findFirst();
            optionalDeviceBO.ifPresent(db -> {
                db.setId(deviceBO.getId());
                update.add(db);
            });
        });

        List<DeviceBO> add = new ArrayList<>();
        deviceBOListForPush.forEach(deviceBO -> {
            if (deviceBOListForProject.stream().noneMatch(deviceBOForProject -> deviceBOForProject.getNumber().equals(deviceBO.getNumber()))) {
                add.add(deviceBO);
            }
        });

        if (!update.isEmpty()) {
            queryDeviceSecondService.updateDevices(update);
        }
        if (!add.isEmpty()) {
            queryDeviceSecondService.addDevices(add);
        }

        log.info("JieShun push carDevice end!");
        return new ResponseCommonPushJieShunDTO(0);
    }

}
